package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.entity.User;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Min;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    ReportMapper reportMapper;

    @Autowired
    WorkspaceService workspaceService;
    /**
     * 统计营业额
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        /**
         * 封装起始日期到结束日期的中间日期，封装到dateList集合
         */
        List<LocalDate> dateList = new ArrayList<>();

        dateList.add(begin);

        //开始时间和结束时间相等时退出循环
        while (!(begin.equals(end))){
                //计算起始日期加一
                begin = begin.plusDays(1);
                dateList.add(begin);
        }
        /**
         * 获取营业额列表
         * select sum(amount) from orders where order_time between #{beginTime} and #{endTime} and Status = #{COMPLETED}
         */

        Map map = new HashMap<>();
        List<BigDecimal> doubleList = new ArrayList<>();
        for (LocalDate localDate : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
            map.put("begin",beginTime);
            map.put("end",endTime);
            map.put("status", Orders.COMPLETED);
            BigDecimal sumAmount = reportMapper.sumAmount(map);
            if (sumAmount == null){
                BigDecimal zero = new BigDecimal("0");
                sumAmount = zero;
            }

           doubleList.add(sumAmount);
        }

        /**
         * 封装返回值 使用StringUtils转成String类型
         */
        String date = StringUtils.join(dateList, ",");
        String sum = StringUtils.join(doubleList,",");

        return TurnoverReportVO.builder()
                .dateList(date)
                .turnoverList(sum)
                .build();
    }

    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO userReport(LocalDate begin, LocalDate end) {
        /**
         * 计算 日期列表
         */
        List<LocalDate> datelist = new ArrayList();//用于存放begin和end中间的日期
        datelist.add(begin);
        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            datelist.add(begin);
        }
        /**
         * 计算 新增用户列表 和 总用户列表哦
         */
        List totalUserList = new ArrayList();
        List newUserList = new ArrayList();
        for (LocalDate localDate : datelist) {
            //计算当前日期人数
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
            //select count(*) from user where create_time &lt; #{endTime}
            Integer totalUser = reportMapper.countAllUser(endTime);//当前日期总人数
            //select count(*) from user where create_time &lt; #{endTime} and create_time &gt; #{beginTime}
            Integer newUser = reportMapper.countNewUser(beginTime,endTime);//当前日期新增人数
            totalUserList.add(totalUser);
            newUserList.add(newUser);
        }
        /**
         * 封装列表
         */
        String dateList = StringUtils.join(datelist, ",");
        String totaluserlist = StringUtils.join(totalUserList, ",");
        String newuserlist =  StringUtils.join(newUserList, ",");
        return UserReportVO.builder()
                .dateList(dateList)
                .newUserList(newuserlist)
                .totalUserList(totaluserlist)
                .build();
    }

    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        /**
         * 计算 日期列表
         */
        List<LocalDate> datelist = new ArrayList();//用于存放begin和end中间的日期
        datelist.add(begin);
        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            datelist.add(begin);
        }
        /**
         * 计算 每日订单数
         */

        List orderCountList = new ArrayList();//每日订单数
        List validOrderCountList = new ArrayList();//每日有效订单数
        Integer totalOrderCount;//订单总数
        Integer validOrderCount1;//有效订单数
        Double orderCompletionRate;//订单完成率
        for (LocalDate localDate : datelist) {
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
            //计算每日订单数
            //select count(*) from orders where order_time >= #{beginTime} and order_time <= #{endTime}
            Integer orderCount = reportMapper.orderCount(beginTime,endTime,null);
            orderCountList.add(orderCount);
            //每日有效订单数，以逗号分隔，例如：20,21,10
            //select count(*) from orders where order_time >= #{beginTime} and order_time <= #{endTime} and status = #{Orders.COMPLETED}
            Integer validOrderCount = reportMapper.orderCount(beginTime,endTime,Orders.COMPLETED);
            validOrderCountList.add(validOrderCount);
        }
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        //订单总数
        //select count(*) from orders where order_time <= #{endTime}
        totalOrderCount = reportMapper.orderCount(null,endTime,null);
        //有效订单数
        //select count(*) from orders where status = #{Orders.COMPLETED}
        validOrderCount1 = reportMapper.orderCount(null,null,Orders.COMPLETED);
        //订单完成率
        Integer totalOrder = reportMapper.orderCount(null,null,null);//所有订单
        orderCompletionRate = (double) validOrderCount1/totalOrder;
        //封装
        String dateList = StringUtils.join(datelist, ",");
        String orderCountList_String = StringUtils.join(orderCountList, ",");
        String validOrderCountList_String = StringUtils.join(validOrderCountList, ",");
        return OrderReportVO.builder()
                .dateList(dateList)
                .orderCountList(orderCountList_String)
                .validOrderCountList(validOrderCountList_String)
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount1)
                .orderCompletionRate(orderCompletionRate)
                .build();
    }
    /**
     * top10菜品名称 及 销量
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        List<GoodsSalesDTO> goodsSalesDTOList = reportMapper.top10(beginTime,endTime);

        List<String> nameList = goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        List<Integer> numbersList = goodsSalesDTOList.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());

        String nameList_String = StringUtils.join(nameList, ",");
        String numbersList_String = StringUtils.join(numbersList, ",");


        return SalesTop10ReportVO.builder()
                .nameList(nameList_String)
                .numberList(numbersList_String)
                .build();
    }
    /**
     * 导出30天数据
     * @param response
     */
    @Override
    public void export(HttpServletResponse response) {
        //获取30天的数据
        LocalDate begin = LocalDate.now().plusDays(-30);
        LocalDate end = LocalDate.now().plusDays(-1);
        BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(begin, LocalTime.MIN), LocalDateTime.of(end, LocalTime.MAX));
        //读取 运营数据报表模板 文件并创建输入流
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        //在内存中创建一个excel
        try {
            XSSFWorkbook excel = new XSSFWorkbook(in);
            XSSFSheet sheet1 = excel.getSheet("sheet1");
            /**
             * 日期
             */
            //为excel表中的日期赋值
            sheet1.getRow(1).getCell(1).setCellValue("开始日期："+begin.toString()+"~结束日期："+end.toString());
            /**
             * 概览数据
             */
            //为excel表中的营业额赋值
            sheet1.getRow(3).getCell(2).setCellValue(businessData.getTurnover());
            //为excel表中的订单完成率赋值
            sheet1.getRow(3).getCell(4).setCellValue(businessData.getOrderCompletionRate());
            //为excel表中的新增用户数赋值
            sheet1.getRow(3).getCell(6).setCellValue(businessData.getNewUsers());
            //为excel表中的有效订单数赋值
            sheet1.getRow(4).getCell(2).setCellValue(businessData.getValidOrderCount());
            //为excel表中的平均客单价赋值
            sheet1.getRow(4).getCell(4).setCellValue(businessData.getUnitPrice());
            /**
             * 明细数据
             */
            for(int i=0;i<30;i++){
                LocalDate localDate = begin.plusDays(i);
                //为表格第七行第二列的 日期字段 赋值
                sheet1.getRow(7+i).getCell(1).setCellValue(localDate.toString());
                    //获取当前日期的数据概览对象
                BusinessDataVO businessData1 = workspaceService.getBusinessData(LocalDateTime.of(localDate, LocalTime.MIN), LocalDateTime.of(localDate, LocalTime.MAX));
                //为表格第七行第三列的 营业额字段 赋值
                sheet1.getRow(7+i).getCell(2).setCellValue(businessData1.getTurnover());
                //为表格第七行第四列的 有效订单数 赋值
                sheet1.getRow(7+i).getCell(3).setCellValue(businessData1.getValidOrderCount());
                //为表格第七行第五列的 订单完成率 赋值
                sheet1.getRow(7+i).getCell(4).setCellValue(businessData1.getOrderCompletionRate());
                //为表格第七行第六列的 平均客单价 赋值
                sheet1.getRow(7+i).getCell(5).setCellValue(businessData1.getUnitPrice());
                //为表格第七行第七列的 新增用户数 赋值
                sheet1.getRow(7+i).getCell(6).setCellValue(businessData1.getNewUsers());
            }
            //获取输出流
            ServletOutputStream outputStream = response.getOutputStream();
            //输出数据
            excel.write(outputStream);
            //关闭资源
            excel.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
